package com.sec.etech.sys.msg;

import cn.hutool.core.collection.CollectionUtil;
import com.sec.etech.org.service.EtechUserUtil;
import com.sec.etech.sys.msg.model.EtechEmailMessage;
import lombok.extern.slf4j.Slf4j;
import org.openbpm.base.core.util.StringUtil;
import org.openbpm.bpm.api.engine.plugin.def.UserAssignRule;
import org.openbpm.bpm.engine.plugin.factory.BpmPluginSessionFactory;
import org.openbpm.bpm.engine.plugin.session.BpmExecutionPluginSession;
import org.openbpm.bpm.engine.plugin.session.BpmUserCalcPluginSession;
import org.openbpm.bpm.engine.plugin.session.impl.DefaultBpmTaskPluginSession;
import org.openbpm.bpm.plugin.node.userassign.executer.UserAssignRuleCalc;
import org.openbpm.form.util.JdbcTemplateUtil;
import org.openbpm.sys.api.freemark.IFreemarkerEngine;
import org.openbpm.sys.api.groovy.IGroovyScriptEngine;
import org.openbpm.sys.api.jms.model.DefaultJmsDTO;
import org.openbpm.sys.api.jms.model.JmsDTO;
import org.openbpm.sys.api.jms.model.msg.NotifyMessage;
import org.openbpm.sys.api.jms.producer.JmsProducer;
import org.openbpm.sys.api.model.SysIdentity;
import org.openbpm.sys.core.manager.MsgTemplateManager;
import org.openbpm.sys.core.model.MsgTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Service("etechMailService")
public class EtechMailService {

    @Value("${etech.email.mode:direct}")
    private String mailMode = "";

    @Resource(name="etechMailHandler")
    EtechMailHandler mailHandler;

    @Autowired
    IFreemarkerEngine freemarkerEngine;

    @Autowired
    MsgTemplateManager msgTemplateManager;

    /**
     * 通用邮件发送
     *
     * @param msg
     * @return
     */
    public boolean sendMail(EtechEmailMessage msg) {
        return sendMail(msg, null);
    }

    public boolean sendMail(EtechEmailMessage msg, Map vars) {
        checkEmail(msg, vars);
        msg = checkTemplate(msg, vars);
        if("queque".equalsIgnoreCase(mailMode)){
            // not support
            // jmsProducer.sendToQueue(getJmsMsgVo(msg, vars));
        }else {
            return mailHandler.sendMail(msg);
        }
        return true;
    }

    /**
     * 通过模板发送邮件（本期项目不需要支持）
     * @param templateKey
     * @param vars
     * @return
     */
    @Deprecated
    public boolean sendMail(String templateKey, Map vars) {
        MsgTemplate template = msgTemplateManager.getByKey(templateKey);
        if (template == null) {
            log.warn("未找到对应消息模板, key={}", templateKey);
            return false;
        }
        EtechEmailMessage msg = new EtechEmailMessage();
        // to/cc
        List<String> tolist = getEmailAddress(template.getTo(), vars);
        if(CollectionUtil.isNotEmpty(tolist)){
            msg.setTo(StringUtil.join(tolist.toArray(new String[tolist.size()]),","));
        }
        List<String> cclist = getEmailAddress(template.getCc(), vars);
        if(CollectionUtil.isNotEmpty(cclist)){
            msg.setCc(StringUtil.join(cclist.toArray(new String[cclist.size()]),","));
        }
        msg.setSubject(template.getSubject());
        msg.setHtmlContent(template.getHtml());
        return sendMail(msg, vars);
    }

    private EtechEmailMessage checkEmail(EtechEmailMessage msg, Map vars) {
        // check to/cc/bcc
        if(StringUtil.isNotEmpty(msg.getTo())){
            msg.setTo(StringUtil.join(getEmailAddress(msg.getTo().split(",")),","));
        }
        if(StringUtil.isNotEmpty(msg.getCc())){
            msg.setCc(StringUtil.join(getEmailAddress(msg.getCc().split(",")),","));
        }
        if(StringUtil.isNotEmpty(msg.getBcc())){
            msg.setBcc(StringUtil.join(getEmailAddress(msg.getBcc().split(",")),","));
        }
        if(StringUtil.isEmpty(msg.getTo()) && StringUtil.isEmpty(msg.getCc()) && StringUtil.isEmpty(msg.getBcc())){
            // throw exception
        }
        return msg;
    }

    private String[] getEmailAddress(String[] userIds){
        if(userIds==null) return null;
        if(userIds[0].indexOf("@")>0){
            return userIds;
        }
        List<String> mailList = new ArrayList<>();
        for(String key: userIds){
            String email = EtechUserUtil.getUserMailByIdOrAccount(key);
            mailList.add(email);
        }
        return mailList.toArray(new String[mailList.size()]);
    }

    private String[] getEmailAddress2(String[] userIds){
        if(userIds==null) return null;
        if(userIds[0].indexOf("@")>0){
            return userIds;
        }
        if(jdbcTemplate==null){
            jdbcTemplate = JdbcTemplateUtil.getJdbcTemplate("dataSourceDefault");
        }
        // TODO 优化措施，调用人员缓存数据
        String ids = StringUtil.join(userIds, ",");
        String sql = "select email_ as email from org_user where account_ in (" + ids + ") or id_ in (" + ids +")";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        List<String> mailList = new ArrayList<>();
        for(Map row: list){
            mailList.add((String)row.get("email"));
        }
        return mailList.toArray(new String[mailList.size()]);
    }

    private JdbcTemplate jdbcTemplate = null;


    private List<String> getEmailAddress(String ruleList, Map vars) {
        // TODO  List<UserAssignRule> => List<email>
        return null;
    }
    private List<SysIdentity> getUser(List<UserAssignRule> ruleList, Map vars) {
        BpmExecutionPluginSession pluginSession = new DefaultBpmTaskPluginSession();
        ((DefaultBpmTaskPluginSession) pluginSession).getVariableScope().getVariables().putAll(vars);
        BpmUserCalcPluginSession calcSession = BpmPluginSessionFactory.buildBpmUserCalcPluginSession(pluginSession);
        return UserAssignRuleCalc.calcUserAssign(calcSession, ruleList, Boolean.valueOf(false));
    }

    private EtechEmailMessage checkTemplate(EtechEmailMessage msg, Map vars) {
        if (CollectionUtil.isNotEmpty(vars)) {
            // subject
            String subject = msg.getSubject();
            if (StringUtil.isNotEmpty(subject)) {
                subject = this.freemarkerEngine.parseByString(subject, vars);
                msg.setHtmlContent(subject);
            }
            // html
            String htmlTemplate = msg.getHtmlContent();
            if (StringUtil.isNotEmpty(htmlTemplate)) {
                htmlTemplate = htmlTemplate.replaceAll("&lt;", "<").replaceAll("&gt;", ">");
                htmlTemplate = this.freemarkerEngine.parseByString(htmlTemplate, vars);
                msg.setHtmlContent(htmlTemplate);
            }
        }
        return msg;
    }

}
